package com.patchmanage.back.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.patchmanage.back.entity.Admin;
import com.patchmanage.back.entity.DepartmentGroup;
import com.patchmanage.back.entity.Inventory;
import com.patchmanage.back.mapper.AdminMapper;
import com.patchmanage.back.service.IDepartmentGroupService;
import com.patchmanage.back.service.IExcelService;
import com.patchmanage.back.service.IInventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huizhao
 * @since 2021-03-20
 */
@Service
public class ExcelServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IExcelService {

    @Autowired
    public IInventoryService inventoryService;

    @Autowired
    public IDepartmentGroupService departmentGroupService;


    /**
     * 导出 资产信息
     * @param response
     * @param inventory
     */
    @Override
    public Boolean exportInventory(HttpServletResponse response, Inventory inventory){

        Map<String, Object> mapParams = BeanUtil.beanToMap(inventory);
        List<Inventory> inventoryList  = inventoryService.listEx(mapParams);

        ExcelWriter writer = ExcelUtil.getWriter();
        writer.setOnlyAlias(true);//设置是否只保留别名中的字段值，如果为true，则不设置alias的字段将不被输出，false表示原样输出
        writer.addHeaderAlias("id", "资产id");
        writer.addHeaderAlias("name", "资产名称");
        writer.addHeaderAlias("departmentName", "资产所属部门");
        writer.addHeaderAlias("ip", "IP地址");
        writer.addHeaderAlias("mac", "MAC地址");
        writer.addHeaderAlias("os", "操作系统");
        writer.addHeaderAlias("safeLv", "安全等级");
        writer.addHeaderAlias("unpatchNum", "未打补丁数");
        writer.addHeaderAlias("disTime", "发现时间");
        writer.addHeaderAlias("isTest", "测试标记");
        writer.addHeaderAlias("isAvailable", "可用标记");

        writer.merge(10, "资产信息表");
        writer.write(inventoryList, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=test.xlsx");

        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            writer.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
        }
        IoUtil.close(out);

        return true;
    }


    /**
     * 导入资产
     * @param file
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    @Async
    public Boolean importInvertory(File file) {
        try{
            ExcelUtil.readBySax(file,0,createInventoryRowHandler());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            file.delete();
        }
        return true;
    }

    /**
     * 导入资产行处理器
     */
    private RowHandler createInventoryRowHandler() {
        return new RowHandler() {
            List<Inventory> inventoryList = new LinkedList<>();
            @Override
            public void handle(int sheetIndex, long rowIndex, List<Object> rowList) {
                Inventory inventory = null;
                if(sheetIndex == 0 && rowIndex > 1
                        && rowList.get(0) !=null && StrUtil.isNotBlank(rowList.get(0).toString())
                        && rowList.get(1) !=null && StrUtil.isNotBlank(rowList.get(1).toString())
                        && rowList.get(2) !=null && StrUtil.isNotBlank(rowList.get(2).toString())){

                    inventory = new Inventory();
                    inventory.setsId(StrUtil.toString(rowList.get(0)));
                    inventory.setName(StrUtil.toString(rowList.get(1)));

                    //插入所属部门
                    QueryWrapper<DepartmentGroup> queryWrapper = new QueryWrapper();
                    queryWrapper.eq("name",StrUtil.toString(rowList.get(2)).trim());
                    List<DepartmentGroup>  departmentGroupList = departmentGroupService.list(queryWrapper);
                    if(departmentGroupList.size() > 0){
                        DepartmentGroup departmentGroup = departmentGroupList.get(0);
                        inventory.setDepartmentName(departmentGroup.getName());
                        inventory.setGroupId(departmentGroup.getId());
                    }

                    inventory.setIp(StrUtil.toString(rowList.get(3)));
                    inventory.setMac(StrUtil.toString(rowList.get(4)));
                    inventory.setOs(StrUtil.toString(rowList.get(5)));
                    inventory.setSafeLv(Convert.toInt(rowList.get(6)));
                    inventory.setUnpatchNum(Convert.toInt(rowList.get(7)));
                    inventory.setDisTime(Convert.toLocalDateTime(rowList.get(8)));
                    inventory.setIsTest(Convert.toInt(rowList.get(9)));
                    inventory.setIsAvailable(Convert.toInt(rowList.get(10)));
                    inventory.setOwner(StrUtil.toString(rowList.get(11)));

                    inventoryList.add(inventory);

                    if(inventoryList.size() == 1000){
                        Boolean saveResult = inventoryService.saveBatch(inventoryList,1000);
                        if(saveResult){
                            inventoryList.clear();
                        }
                    }
                }
            }
        };
    }
}
